package com.apestech.api.workflow.lib;

import com.apestech.api.workflow.extend.FlowDatabase;
import com.apestech.api.workflow.lib.element.FlowExecute;
import com.apestech.api.workflow.lib.element.FlowQuery;
import com.apestech.api.workflow.lib.element.FlowTask;
import com.apestech.api.workflow.lib.element.WorkProcessEngine;
import com.apestech.framework.db.SqlSession;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.util.StringUtil;

import java.util.ArrayList;
import java.util.Map;

/**
 * 公共静态类
 *
 * @author hup
 * @create 2018-07-21-14:16
 */
public class FlowUtil extends StringUtil{

    public enum ExtendDbType {
        NORMAL(0), CHANGE_SIGN(1), START_COUNTER_SIGN(2), COUNTER_SIGN(3),
        START_ADD_SIGN(4), ADD_SIGN(5), ADD_CHANGE_SIGN(6), ADD_START_COUNTER_SIGN(7),
        ADD_COUNTER_SIGN(8), REFOULEMENT(9), ROLLBACK(10);
        int value;
        ExtendDbType(int value) {
            this.value = value;
        }
        public int getValue() {
            return value;
        }
    }

    /**
     * 获取FlowTask对象，如input参数不为null，将会开启路由数据合法性校验
     * @param input
     * @return
     * @throws Exception
     */
    public FlowTask getFlowTask(WorkProcessEngine engine, JSONObject input) throws Exception {
        FlowTask flowTask= new FlowTask(engine, input);
        if(flowTask.getTask()==null){
            throw new Exception("当前任务结点不存在！");
        }
        flowTask.getExecNode();
        return flowTask;
    }

    /**
     * 前端数据输入有效性判断，分扩展和非扩展结点两种情况
     * @param taskId
     * @param input
     * @return
     */
    public JSONObject getTaskMap(WorkProcessEngine engine, String taskId, JSONObject input){
        boolean flag=false;
        JSONObject taskMap=null;
        Map m=engine.getTaskService().getVariables(taskId);
        if(m!=null){
            if(m.get("nodeUserId")==null){
                flag=true;
            }
            taskMap=new JSONObject(m);
        }
        if(taskMap==null){
            flag=true;
            taskMap=new JSONObject();
        }
        if(flag){
            taskMap.put("nodeUserId", input.getString("loginUserId"));
            taskMap.put("nodeUserName", input.getString("loginUserName"));
            engine.getTaskService().setVariables(taskId, taskMap);
        }
        return taskMap;
    }

    /**
     * 结点输入数据有效性判断
     * @param input
     * @param extend
     * @throws Exception
     */
    public void preInputValidate(JSONObject input, boolean extend) throws Exception {
        if(input.get("processInstanceId")==null && input.get("taskId")==null){
            throw new Exception("流程编码或者任务编码不允许为空！");
        }
        if(input.get("userId")==null){
            throw new Exception("人员编码不允许为空！");
        }
        if(input.get("loginUserId")==null){
            throw new Exception("登录人员不允许为空！");
        }

        if(extend){
            /*if(input.get("opinion")==null){
                throw new Exception("意见不允许为空！");
            }
            if(input.get("result")==null){
                throw new Exception("结果不允许为空！");
            }*/
        }
    }

    /**
     * 记录扩展结点操作信息，存ORACLE数据库
     * @param input 必填字段：processInstanceId，businessKey，userId，userName，opinion，result； 非必填：loginUserId，loginUserName
     * @param taskId
     * @param taskName
     * @param type
     * @throws Exception
     */
    public void writeTaskDb(WorkProcessEngine engine, SqlSession session, JSONObject input, String taskId, String taskName, ExtendDbType type) throws Exception {
        FlowDatabase db=new FlowDatabase(session);
        if(input.get("result")==null){
            input.put("result",0);
        }
        if(input.get("businessKey")==null){
            FlowQuery query=new FlowQuery(engine);
            JSONObject j=new JSONObject();
            j.put("processInstanceId", input.getString("processInstanceId"));
            JSONArray list=query.getProcList(j);
            if(list!=null){
                j= (JSONObject) list.get(0);
                input.put("businessKey", j.get("businessKey"));
            }
        }
        db.writeNodeLog(input.getString("processInstanceId"),
                input.getString("businessKey"),
                input.getString("userId"),
                input.getString("userName"),
                input.getString("opinion"),
                input.getInteger("result"),
                input.getString("loginUserId"),
                input.getString("loginUserName"),
                input.getString("counterUserId"),
                input.getString("counterUserName"),
                taskId, taskName, type.getValue());
    }

    /**
     * 用户签收
     * @param taskId
     * @param input
     * @throws Exception
     */
    public void claimUser(WorkProcessEngine engine, String taskId, JSONObject input) throws Exception {
        getTaskMap(engine, taskId, input);
        FlowExecute exec=new FlowExecute(engine);
        exec.claimTask(taskId, input.getString("userId"));
    }

    /**
     *
     * @param taskId
     * @return
     * @throws Exception
     */
    public ArrayList<String> getTaskUserList(WorkProcessEngine engine, String taskId) throws Exception {
        FlowQuery query=new FlowQuery(engine);
        return query.getTaskUserList(taskId);
    }

    public String getCommission(WorkProcessEngine engine, String userId) throws Exception {
        FlowDatabase db=new FlowDatabase(engine);
        return db.getCommission(userId, null).getId();
    }

    public FlowDatabase.UserInfo getCommission(WorkProcessEngine engine, String userId, String userName) throws Exception {
        FlowDatabase db=new FlowDatabase(engine);
        return db.getCommission(userId, null);
    }

}
